{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "# 对象的内容"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## self:表示对象本身，用来调用类方法和类属性,而且是默认带上的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 在pycharm中使用jupyter notebook 的方法\n",
    "- 下载jupyter： \n",
    "\t- 切换到 D:\\应用程序\\python\\Scripts 就是你的python安装目录\n",
    "\t- cmd 下执行 pin install jupyter\n",
    "- cmd下输入jupyter notebook ,开启jupyter\n",
    "- 在pycharm中输入代码，执行：在url中输入cmd中给出的地址即可"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## self详解\n",
    "- 一般函数都会有一个self参数，用于实例化对象的调用 power.doHomework()相当于把power当成参数\n",
    "- 如果一个函数没有self参数，那么只能有使用类调用方式 Stuedent.doHoomework()\n",
    "- __init__是构造函数，只要是使用这个类就肯定会执行\n",
    "- __class__ 调用类成员"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "i am power and now is 19\nmy name is None\n"
     ]
    }
   ],
   "source": [
    "class Student():\n",
    "    name = None\n",
    "    age = 18\n",
    "    course = 'python'\n",
    "    def __init__(self):\n",
    "        self.name='power'\n",
    "    def doHomeword(self,now):\n",
    "        print ('i am {} and now is {}'.format(self.name,now))\n",
    "    def say():\n",
    "        print(\"my name is {}\".format(__class__.name))\n",
    "        \n",
    "power = Student()\n",
    "power.doHomeword(19)\n",
    "Student.say()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 封装：对对象的成员进行访问限制\n",
    "- 虽然分为public，provate和protected但是他们三个并不是关键字\n",
    "- provate是变量前加入两个下划线，protected加一个下划线、"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "power\n14\n14\n"
     ]
    }
   ],
   "source": [
    "class A():\n",
    "    name = 'power'\n",
    "    _age = 14\n",
    "    __size = 20\n",
    "    def do(self):\n",
    "        print(self._age)\n",
    "print(A.name)\n",
    "a = A()\n",
    "a.do()\n",
    "print(A._age)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 继承：增加代码复用性，避免重复造轮子\n",
    "- 子类继承父类的所有非私有属性和函数方法\n",
    "- 子类继承的内容只是一种引用而不是赋值\n",
    "- 所有的类都有一个公共的父类object  class A():  class B(A):这就是B继承A\n",
    "- super().属性/方法  用来调用父类的方法或者属性\n",
    "- __init__也存在继承机制"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "i am an animal\ni am a  dog\n"
     ]
    }
   ],
   "source": [
    "class Animal():\n",
    "    def __init__(self):\n",
    "        print('i am an animal')\n",
    "class Dog(Animal):\n",
    "    # 函数的重构\n",
    "    def __init__(self):\n",
    "        # 调用父类的方法\n",
    "        super().__init__()\n",
    "        print('i am a  dog')\n",
    "kaka = Dog()   \n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "A\n"
     ]
    }
   ],
   "source": [
    "# 如果出现一个类继承多个类的情况，按照顺序获得相同的属性或者方法\n",
    "class A():\n",
    "    name='A'\n",
    "class B():\n",
    "    name='B'    \n",
    "class C(A,B):\n",
    "    def say(self):\n",
    "        print(self.name)\n",
    "c = C()\n",
    "c.say()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 多态：同一个对象在不同情况下的有不同的形态，主要通过多继承的方式实现，继承一个类只是多实现一个功能而已，不继承对子类没有影响"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 类常用函数\n",
    "- issubClass(A,b) : A是不是B的子类\n",
    "- isinstance(a,A) : a是不是Ad的一个实例\n",
    "- hasattr(A,'name') : A 是否有一个属性name\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\nTrue\nTrue\nA\n"
     ]
    },
    {
     "ename": "TypeError",
     "evalue": "'<' not supported between instances of 'type' and 'type'",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-30-c9efb1a615e8>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      8\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mhasattr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mA\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;34m'name'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      9\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mgetattr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mA\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;34m'name'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 10\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mA\u001b[0m\u001b[1;33m<\u001b[0m\u001b[0mB\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: '<' not supported between instances of 'type' and 'type'"
     ],
     "output_type": "error"
    }
   ],
   "source": [
    "class A():\n",
    "    name='A'\n",
    "class B(A):\n",
    "    name='B'\n",
    "a = A()\n",
    "print(issubclass(B,A))\n",
    "print(isinstance(a,A))\n",
    "print(hasattr(A,'name'))\n",
    "print(getattr(A,'name'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "POWER 11\n"
     ]
    }
   ],
   "source": [
    "# 对对象属性在类中规范一下\n",
    "class A():\n",
    "    def __init__(self,name,age):\n",
    "        self.name=name.upper()\n",
    "        self.age=int(age)\n",
    "a = A('pOwer',11.2)\n",
    "print(a.name,a.age)\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 类的内置属性\n",
    "- __dict__ :类的属性，已字典的方式返回\n",
    "- __doc__ : 类的说明文档\n",
    "- __name__ ：类的名称\n",
    "- __bases__ : 类的所有父类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'__module__': '__main__', '__doc__': '\\n    这是学生的一个类，用于描述学生的信息\\n    ', 'name': 'power', 'age': 18, '__getattr__': <function Student.__getattr__ at 0x0000025D7103B1E0>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>}\n\n    这是学生的一个类，用于描述学生的信息\n    \nStudent\n(<class 'object'>,)\n该类型不存在的属性course\nNone\n"
     ]
    }
   ],
   "source": [
    "class Student():\n",
    "    '''\n",
    "    这是学生的一个类，用于描述学生的信息\n",
    "    '''\n",
    "    name = 'power'\n",
    "    age = 18\n",
    "    def __getattr__(self, item):\n",
    "        print('该类型不存在的属性{}'.format(item))\n",
    "print(Student.__dict__)\n",
    "print(Student.__doc__)\n",
    "print(Student.__name__)\n",
    "print(Student.__bases__)\n",
    "a = Student()\n",
    "a.name='lsl'\n",
    "# 访问一个并不存在的属性\n",
    "print(getattr(a,'course'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## TIPs:如果在jupyter出现不对的输出，需要刷新一下"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 类的魔术方法\n",
    "- 特点：不用调用，自动运行\n",
    "- 例子\n",
    " \t- '__init__()':构造函数\n",
    "\t- '__call__()': 把对象当成函数时使用时调用的函数\n",
    "\t-  '__str__()': 把对象当作字符串时使用的函数\n",
    "\t- __setattr__(A,name,value): 设置一个不存在的属性\n",
    "       "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\nNone\npower\n"
     ]
    }
   ],
   "source": [
    "class A():\n",
    "    def __getattr__(self, item):\n",
    "        pass\n",
    "    \n",
    "a = A()\n",
    "# a.name='power'\n",
    "print(getattr(a,'name'))   # 如果没有__getatr__就会报错\n",
    "print(setattr(a,'name','power'))\n",
    "print(a.name)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  \\_\\_lt\\_\\_用于比较两个对象的大小关系，主要是比较他们的某个属性"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<__main__.Person object at 0x00000175F0AC7588> 会比 <__main__.Person object at 0x00000175F0AC7550> 大吗？\nTrue\n"
     ]
    }
   ],
   "source": [
    "class Person():\n",
    "    def __gt__(self, other):\n",
    "        print(\"{0} 会比 {1} 大吗？\".format(self,other))\n",
    "        return self.age>other.age\n",
    "a = Person()\n",
    "a.age = 18\n",
    "b = Person()\n",
    "b.age = 17\n",
    "print(a>b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 类和对象的三个方法\n",
    "- 实例方法：必须要实例化才能使用的方法\n",
    "- 类方法 ： 不用实例化也能使用的方法\n",
    "- 静态方法 ： 不需要任何参数的方法,同样不需要实例化的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class '__main__.Person'>\nplay...\nsay...\n<__main__.Person object at 0x00000175F0AD5DD8>\neat...\n<class '__main__.Person'>\nplay...\nsay...\n"
     ]
    }
   ],
   "source": [
    "class Person():\n",
    "    # 这是一个实例方法\n",
    "    def eat(self):\n",
    "        print(self)\n",
    "        print('eat...')\n",
    "    # 这是一个类方法\n",
    "    @classmethod\n",
    "    def play(cls):\n",
    "        print(cls)\n",
    "        print('play...')\n",
    "    # 这是一个静态方法\n",
    "    @staticmethod\n",
    "    def say():\n",
    "        print('say...')\n",
    "a = Person()\n",
    "# 如果直接用类来访问\n",
    "Person.play()\n",
    "Person.say()\n",
    "# 实例化访问\n",
    "a.eat()\n",
    "a.play()\n",
    "a.say()\n",
    "        \n",
    "     \n",
    "     \n",
    "     "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 成员描述符\n",
    "- property（fget,fset,fdel,'描述'）\n",
    "- 目的：为了使获取，设置，删除一个属性是增加一些操作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "fset\nPOWERLSL\n"
     ]
    }
   ],
   "source": [
    "class A():\n",
    "    def fget(self):\n",
    "        return self.name.upper()\n",
    "    def fset(self,name):\n",
    "        print('fset')\n",
    "        self.name=name+\"lsl\"\n",
    "    def fdel(self):\n",
    "        print('fdel')\n",
    "    # 主要还是对name1的操作\n",
    "    name1 = property(fget,fset,fdel,'对name的一个操作')\n",
    "a = A()\n",
    "a.name1='power'\n",
    "print(a.name1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 抽象类和抽象方法：使子类方法具有统一的规范\n",
    "- 抽象类不能够被实例化，如果子类没有完全实现抽象方法，则不能够被实例化\n",
    "- 抽象类的使用需要借助abc模块    import abc\n",
    "- 抽象类可以有属性，可以有抽象方法和具体方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
